<script setup lang="ts">
import {onMounted, ref, watch} from "vue";
import { ElMessageBox } from 'element-plus'
import {service} from "@/utils";
import store from '@/store'
import Process from './process.vue'
import Computer from './computer.vue'
import EditSession from './edit-session.vue'


const {user} = store.userStore;

const sessionTreeRef = ref();
const editSessionRef = ref<InstanceType<typeof EditSession>>();
const sessionTreeLoading = ref(false);
const sessionList = ref([]);
const currentSession = ref();
const sessionOpenList = ref<Array<any>>([]);

const onLoadSession = () => {
    service.get('/ssh/session', {owner: user?.userId}).then(({code, data}) => {
        if (code === 200) {
            sessionList.value = data;
        } else {
            sessionList.value = []
        }
    })
}

const onSessionOpen = (value: any) => {
    if (value) {
        const index = sessionOpenList.value.findIndex((item:any) => item.id === value.id);
        if (index === -1) {
            sessionOpenList.value.push(value)
        }
        currentSession.value = value.id;
    }
}

const onEditSession = (type: string, data?: any) => {
    if (!data) {
        data = {owner: user.userId}
    }
    editSessionRef.value?.open({
        data: data,
        type: type === 'create'? 'post':'put',
        confirm: (resolve: (value: any)=> void, form: any, operate: AxiosMethod) => {
            service[operate]('/ssh/session', form).then(({code}) => {
                code === 200 && onLoadSession();
                resolve(code)
            })
        }
    })
}

const onCopySession = (data: any) => {
    ElMessageBox.confirm(`确定复制${data.host}:${data.port}/${data.username}会话?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(() => {
        let session: {[key:string]:any} = {...data}
        delete session.id
        delete session.createTime
        service.post('/ssh/session', session).then(({code}) => {
            code === 200 && onLoadSession();
        })
    }).catch(() => {});
}

const onDeleteSession = (data: any) => {
    service.confirm(`确定删除${data.host}:${data.port}/${data.username}会话及其所有进程信息?`, {
        url: '/ssh/session',
        data: {id: data.id},
        success: () => {
            onCloseSession(data.id);
            onLoadSession();
        }
    })
}

const onCloseSession = (id: any) => {
    const tabs = sessionOpenList.value
    let active = currentSession.value
    if (active === id) {
        tabs.forEach((tab: { [key:string]: any }, index: number) => {
            if (tab.id === id) {
                const nextTab = tabs[index + 1] || tabs[index - 1]
                if (nextTab) {
                    active = nextTab.id
                }
            }
        })
    }

    sessionOpenList.value = tabs.filter((tab: any) => tab.id !== id)
    if (sessionOpenList.value.length === 0) {
        currentSession.value = undefined
    } else {
        currentSession.value = active
    }
}

//树过滤
const sessionFilterText = ref('')
const sessionFilterNode = (value: any, data: any) => {
    if (!value) return true;
    const targetText = data.host;
    return targetText.indexOf(value) !== -1;
}
watch(sessionFilterText, (val) =>  sessionTreeRef.value.filter(val))



onMounted(() => onLoadSession())
</script>

<template>
    <el-container>
        <el-aside v-loading="sessionTreeLoading" width="300px">
            <el-container>
                <el-header>
                    <el-input v-model="sessionFilterText" clearable placeholder="输入关键字进行过滤"></el-input>
                    <el-button icon="el-icon-refresh" type="primary" @click="onLoadSession()" style="margin-left: 5px"/>
                </el-header>
                <el-main class="kt-main">
                    <el-tree ref="sessionTreeRef" :data="sessionList" :expand-on-click-node="true" :filter-node-method="sessionFilterNode" :highlight-current="true"
                             node-key="id" class="menu"
                             :icon="Computer">
                        <template #default="{ node, data }">
                            <span class="custom-tree-node">
                                <span class="label">{{ data.host }}:{{ data.port }}</span>
                                <span class="code">{{ data.username }}</span>
								                <span class="do">
                                    <el-button icon="el-icon-edit" circle link @click.stop="onEditSession('update', data)"/>
                                    <el-button icon="el-icon-copy-document" circle link @click.stop="onCopySession(data)"/>
                                    <el-button icon="el-icon-delete"  circle link @click.stop="onDeleteSession(data)"/>
                                    <el-button v-auth="'secure:ssh:view:precess'" circle link @click.stop="onSessionOpen(data)"/>
								                </span>
							              </span>
                        </template>
                    </el-tree>
                </el-main>
                <el-footer style="height:42px;border: 1px dashed var(--el-border-color)">
                    <el-button icon="el-icon-plus" style="width: 100%;"  link @click="onEditSession('create')">会话</el-button>
                </el-footer>
            </el-container>
        </el-aside>
        <el-main style="padding: 2px 0;overflow: hidden;">
            <el-tabs v-model="currentSession" type="card" closable @tab-remove="onCloseSession">
                <el-tab-pane v-for="item in sessionOpenList" :key="item.id" :label="`${item.username}@${item.host}:${item.port}`" :name="item.id">
                    <process :sessions="sessionList" :session-id="item.id" :owner="item.owner"/>
                </el-tab-pane>
            </el-tabs>
        </el-main>

        <edit-session ref="editSessionRef"/>
    </el-container>
</template>

<style scoped>
.el-tabs :deep(.el-tabs__header) {
    margin: 0;
}

.menu :deep(.el-tree-node__expand-icon.is-leaf) {
    visibility: unset;
}

.custom-tree-node {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 20px;
    height: 100%;
}

.custom-tree-node .code {
    font-size: 12px;
    color: #999;
}

.custom-tree-node .status {
    font-size: 12px;
    color: #999;
}

.custom-tree-node .do {
    display: none;
}


.custom-tree-node .do > .el-button + .el-button {
    margin-left: 8px;
}

.custom-tree-node .do > .el-button.is-circle{
    width: auto;
}

.custom-tree-node .do > .el-button.is-link{
    padding: 0;
}

.custom-tree-node:hover .code {
    display: none;
}

.custom-tree-node:hover .status {
    display: none;
}

.custom-tree-node:hover .do {
    display: inline-block;
}

</style>